package cminus.graph;





import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Hashtable;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

public class PrintGraphics {
	public BufferedImage bi = null;
    public Graphics2D g2 = null;
    public double length = 0.0; 
    public int width;
 
    /** 
     * 获取图像的实际长度
     * 因为画布定义的长度是其宽度的10倍，所以最后会根据使用的实际长度进行截取
     */
    public int getLength(){
        return (int)this.length+20;
    }
 
    /**
     * 初始化画布BufferedImage和画笔Graphics2D，其中宽度为参数，长度为宽度的10倍
     * 画布背景为白色，画笔为黑色
     */
    public void initBuff(int width){
        int height =width;
        this.bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        this.g2 = (Graphics2D)this.bi.getGraphics();
        this.g2.setBackground(Color.WHITE);
        this.g2.clearRect(0, 0, width, height);
        this.g2.setPaint(Color.BLACK);
        this.width = width;
    }
 
    // 根据初始的字体属性值对字体进行设置
    public Font setFontProperty(FontProperty fp){
        int fontStyle = 0;
        int fontFlag = 0;
 
        if(fp.sFace != ""){
            String fontNames[];
            //获取系统所有字体列表，然后判断用户指定的字体是否存在
            fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
            for(int i=0;i<fontNames.length;i++){
                if(fontNames[i].equals(fp.sFace)){
                    fontFlag = 1;
                    break;
                }
            }
            //如果不存在则留空，表示使用系统默认字体
            if(fontFlag == 0){
                System.out.println("Your font face \"" + fp.sFace + "\" is not exist, default is used.");
                fp.sFace = "";
            }
        }
 
        Font font = null;
 
        //设置粗体
        if(fp.bBold){
            fontStyle = 1;
            font = new Font(fp.sFace, Font.BOLD, fp.iSize);
        }
 
        //设置斜体
        if(fp.bItalic){
            if(fontStyle == 0){
                fontStyle = 1;
                font = new Font(fp.sFace, Font.ITALIC, fp.iSize);
            }
            else{
                font = new Font(fp.sFace, Font.BOLD|Font.ITALIC, fp.iSize);
            }
        }
 
        //设置常规体
        if(fontStyle == 0){
            font = new Font(fp.sFace, Font.PLAIN, fp.iSize);
        }
 
        //设置下划线和删除线
        if(fp.bUnderLine || fp.bStrikeout){
            Hashtable<TextAttribute, Object> map = new Hashtable<TextAttribute, Object>();
            if(fp.bUnderLine){
                map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
            }
            if(fp.bStrikeout){
                map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
            }
            font = font.deriveFont(map);
        }
        return font;
    }
 
    //设置线宽
    public Stroke setLineWidth(double width){
        String f = "" + width + "f";
        Stroke stk = new BasicStroke(Float.parseFloat(f));
        return stk;
    }
 
    //使用指定的字体绘制文本，其中(x,y)是指文本起始位置的左下点坐标，所以y不可为0
    public void drawText(double x, double y, String nStr, FontProperty fp){
        Font font = this.setFontProperty(fp);
        this.g2.setFont(font);
        this.g2.drawString(nStr, (int)x, (int)y);
        if(this.length < y){
            this.length = y;
        }
    }
 
    //使用指定的宽度绘制直线，其中(x1,y1)为起始点坐标，(x2,y2)为终点坐标
    public void drawLine(double x1, double y1, double x2, double y2, double w){
        Stroke stk = this.setLineWidth(w);
        this.g2.setStroke(stk);
        this.g2.draw(new Line2D.Double(x1, y1, x2, y2));
        //获取画布实际使用长度，下同
        double max = 0;
        max = y1>y2?y1:y2;
        if(this.length < max){
            this.length = max;
        }
    }
 
    //使用指定的宽度绘制矩形或方型，其中(x1,y1)为左上角坐标，width和height分别指定矩形或方型的宽度及高度
    public void drawRectangle(double x, double y, double width, double height, double w){
        Stroke stk = this.setLineWidth(w);
        this.g2.setStroke(stk);
      //  this.g2.draw(new Rectangle2D.Double(x, y, width, height));
        this.g2.draw(new Ellipse2D.Double(x, y, width, height));
        if(this.length < y+height){
            this.length = y+height;
        }
    }
 
    //将图像通过frame窗口显示出来
    public void printShow(){
        JFrame jframe = new JFrame();
        JPanel allpanel = new JPanel();  
        jframe.setTitle("Preview Image");
        //设置frame是，长度和宽度都适当的增加了一点，这样最终的图片周边会留点白边，比较好看
        jframe.setSize(this.width+20, this.getLength()+40);
        //为frame窗口添加关闭属性
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        //根据实际图像长度截取图像，(0,0)表示图像左上点坐标，后两个参数表示右下角坐标
        BufferedImage img = this.bi.getSubimage(0,0,this.width,this.getLength());
        ImageIcon ii = new ImageIcon(img);
        JLabel lb = new JLabel(ii);
        allpanel.add(lb);
        JScrollPane Scroll = new JScrollPane(allpanel);
        Scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        jframe.getContentPane().add(Scroll);
        //jframe.add(lb);
 
        //显示frame窗口
        jframe.setVisible(true);
        //销毁g2对象
        this.g2.dispose();
    }
}
